package com.ruoyi.elebook.service.impl;

import com.itextpdf.text.DocumentException;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.file.FileTypeUtils;
import com.ruoyi.elebook.domain.BookElebook;
import com.ruoyi.elebook.domain.BookElebookVo;
import com.ruoyi.elebook.domain.BookPage;
import com.ruoyi.elebook.mapper.BookElebookMapper;
import com.ruoyi.elebook.mapper.BookPageMapper;
import com.ruoyi.elebook.service.IBookElebookService;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.domain.SysFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 电子书Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-11
 */
@Service
public class BookElebookServiceImpl implements IBookElebookService
{
    @Autowired
    private BookElebookMapper bookElebookMapper;
    @Autowired
    private RemoteFileService remoteFileService;
    @Autowired
    private BookPageMapper bookPageMapper;
    /**
     * 查询电子书
     *
     * @param id 电子书主键
     * @return 电子书
     */
    @Override
    public BookElebook selectBookElebookById(Long id)
    {
        return bookElebookMapper.selectBookElebookById(id);
    }

    /**
     * 查询电子书列表
     *
     * @param bookElebook 电子书
     * @return 电子书
     */
    @Override
    public List<BookElebook> selectBookElebookList(BookElebook bookElebook)
    {
        return bookElebookMapper.selectBookElebookList(bookElebook);
    }

    /**
     * 新增电子书
     *
     * @param bookElebook 电子书
     * @return 结果
     */
    @Override
    public int insertBookElebook(BookElebook bookElebook)
    {
        bookElebook.setCreateTime(DateUtils.getNowDate());
        return bookElebookMapper.insertBookElebook(bookElebook);
    }

    /**
     * 修改电子书
     *
     * @param bookElebook 电子书
     * @return 结果
     */
    @Override
    public int updateBookElebook(BookElebook bookElebook)
    {
        bookElebook.setUpdateTime(DateUtils.getNowDate());
        return bookElebookMapper.updateBookElebook(bookElebook);
    }

    /**
     * 批量删除电子书
     *
     * @param ids 需要删除的电子书主键
     * @return 结果
     */
    @Override
    public int deleteBookElebookByIds(Long[] ids)
    {
        return bookElebookMapper.deleteBookElebookByIds(ids);
    }

    /**
     * 删除电子书信息
     *
     * @param id 电子书主键
     * @return 结果
     */
    @Override
    public int deleteBookElebookById(Long id)
    {
        return bookElebookMapper.deleteBookElebookById(id);
    }


    /**
     * 上传文件
     *
     * @param bookElebookVo 电子书主键
     * @return 结果
     */
    @Override
    public int insertFile(BookElebookVo bookElebookVo) throws IOException, DocumentException {
            R<SysFile> fileResult = remoteFileService.upload(bookElebookVo.getFile());
            String url = fileResult.getData().getUrl();
            BookElebook bookElebook = new BookElebook();
            bookElebook.setId(bookElebookVo.getId());
            bookElebook.setFileUrl(url);
            bookElebook.setFileName(bookElebookVo.getFile().getOriginalFilename());
            PDDocument document = PDDocument.load(bookElebookVo.getFile().getInputStream());
            int numberOfPages = document.getNumberOfPages();
            bookElebook.setFilePages((long) numberOfPages);
            if (FileTypeUtils.getExtension(bookElebookVo.getFile()).equals("pdf")) {
                ExecutorService executor = Executors.newSingleThreadExecutor();
                // 提交一个Runnable任务到ExecutorService
                Future<?> future = executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            changePdfToImage(bookElebookVo);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        return bookElebookMapper.updateBookElebook(bookElebook);
    }
    @Async
    @Transactional
    public void changePdfToImage(BookElebookVo bookElebookVo) throws IOException {
        List<String> result = new ArrayList<String>();
        try (PDDocument document = PDDocument.load(bookElebookVo.getFile().getInputStream())) {
            int numberOfPages = document.getNumberOfPages();
            // 创建PDF渲染器
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < numberOfPages; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 300, ImageType.RGB);
                String fileName =  String.valueOf(i) + "1";
                R<SysFile> sysFileR =  saveImage(image,fileName);
                BookPage bookPage = new BookPage();
                bookPage.setPageSort((long) i+1);
                bookPage.setPageUrl(sysFileR.getData().getUrl());
                bookPage.setPageName(sysFileR.getData().getName());
                bookPage.setElebookId(bookElebookVo.getId());
                if(i==0){
                    bookPage.setIsCover(1);
                }
                bookPageMapper.insertBookPage(bookPage);
            }
        } catch (IOException e) {
            System.err.println("Error converting PDF to images: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private R<SysFile> saveImage(BufferedImage image,String fileName) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "png", outputStream);
        byte[] bytes = outputStream.toByteArray();
        // 创建一个 MultipartFile 对象
        return remoteFileService.upload( new MockMultipartFile(fileName, fileName, "image/png", bytes));
    }


    /**
     * 获取页数
     *
     * @param BookElebookId 电子书主键
     * @return 结果
     */
    @Override
    public Long selectPageByElebookId(Long BookElebookId)
    {
        return bookElebookMapper.selectPageByElebookId(BookElebookId);
    }

    @Override
    public Integer selectStatus(String accessUrl) {
        return bookElebookMapper.selectStatus(accessUrl);
    }
}
